#include "longCmdServer.h"

static threadPool longPool; 

//长命令监听线程的启动参数
typedef struct LongCmdArg_s {
    int listenfd;
} LongCmdArg;


static void* long_cmd_thread_func(void *arg)
{
    LongCmdArg *lcarg = (LongCmdArg*)arg;
    int sockfd_long   = lcarg->listenfd;
    free(lcarg);

    int epfd = epoll_create(1);
    epoll_add(epfd, sockfd_long);

    conn_info client_l[1024];
    memset(client_l, 0, sizeof(client_l));

    int index_l[1024];
    int idx = 0;
    for (int i = 0; i < 1024; i++) {
        client_l[i].netfd = -1;

        client_l[i].is_alive = 0;
        memset(client_l[i].user_name, 0, sizeof(client_l[i].user_name));
        index_l[i] = -1;
    }

    struct epoll_event ready[1024];
    printf("Long command server (port 21345) started...\n");

    while(1) {
        int ready_num = epoll_wait(epfd, ready, 1024, -1);
        for(int i=0; i<ready_num; i++) {
            int fd = ready[i].data.fd;
            if(fd == sockfd_long) {
                // 新长命令客户端
                int netfd = accept(sockfd_long, NULL, NULL);
                epoll_add(epfd, netfd);

                index_l[netfd] = idx;
                client_l[idx].netfd  = netfd;
                client_l[idx].is_alive = 1;
                idx++;

                printf("[LongCmd] client connected.\n");
            }
            else {
                // 处理长命令
                int idx_l = index_l[fd];
                TLV tlv;
                memset(&tlv, 0, sizeof(tlv));
                int ret_recv = recv_tlv(fd, &tlv);
                if(ret_recv <= 0) {
                    //断开
                    epoll_del(epfd, fd);
                    client_l[idx_l].is_alive = 0;
                    client_l[idx_l].netfd = 0;
                    index_l[fd]   = -1;
                    printf("[LongCmd] client disconnected.\n");
                    close(fd);
                    continue;
                }
                // 分析长命令
                Task t;
                memset(&t, 0, sizeof(t));
                pthread_mutex_lock(&longPool.mutex);
                if(analyze(tlv.jwt, tlv.data, &t, fd,epfd, &longPool, client_l,index_l)!=0){
                    continue;
                }
                enque(&longPool.queue, t);
                pthread_cond_broadcast(&longPool.cond);
                pthread_mutex_unlock(&longPool.mutex);
            }
        }
    }

    close(sockfd_long);
    close(epfd);
    pthread_exit(NULL);
}


//对外暴露的函数：启动长命令服务器(9999)，创建 longPool
int start_long_cmd_server(int long_num,char *ip,char *port)
{

    threadPool_init(&longPool, long_num);
    threadPool_make_worker(&longPool);

    int sockfd_long = tcp_init(ip, port);
    if(sockfd_long < 0) {
        perror("tcp_init long");
        return -1;
    }

    LongCmdArg *lcarg = (LongCmdArg*)calloc(1, sizeof(LongCmdArg));
    lcarg->listenfd = sockfd_long;

    pthread_t tid;
    int ret = pthread_create(&tid, NULL, long_cmd_thread_func, lcarg);
    if(ret != 0) {
        perror("pthread_create long_cmd_thread");
        return -1;
    }
    pthread_detach(tid);

    return 0;
}

